#SF Mapping of Edmonton.
#Install packages, library
# install.packages("sf")
# install.packages("tmap")
# install.packages("ggmap")
# install.packages("ggthemes")
# install.packages("rgeos")
# install.packages("grid")
# install.packages("gridExtra")
# install.packages("reshape2")
# install.packages("scales")
# install.packages(c("rgdal", "htmlwidgets"), dependencies = TRUE)
#install.packages("rgdal")
#install.packages("geojsonsf")
library(geojsonsf)
package 㤼㸱geojsonsf㤼㸲 was built under R version 4.0.5
library(sf)
library(sp)
library(tmap)
package 㤼㸱tmap㤼㸲 was built under R version 4.0.5
library(dplyr)
library(maptools)
Checking rgeos availability: TRUE
library(ggmap)
package 㤼㸱ggmap㤼㸲 was built under R version 4.0.5Google's Terms of Service: https://cloud.google.com/maps-platform/terms/.
Please cite ggmap if you use it! See citation("ggmap") for details.
library(forcats)
library(ggthemes)
package 㤼㸱ggthemes㤼㸲 was built under R version 4.0.5
library(rgeos)
package 㤼㸱rgeos㤼㸲 was built under R version 4.0.5rgeos version: 0.5-5, (SVN revision 640)
GEOS runtime version: 3.8.0-CAPI-1.13.1
Linking to sp version: 1.4-5
Polygon checking: TRUE
library(broom)
library(plyr)
--------------------------------------------------------------------------------------------------------------------------------------------------
You have loaded plyr after dplyr - this is likely to cause problems.
If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
library(plyr); library(dplyr)
--------------------------------------------------------------------------------------------------------------------------------------------------
Attaching package: 㤼㸱plyr㤼㸲
The following objects are masked from 㤼㸱package:dplyr㤼㸲:
arrange, count, desc, failwith, id, mutate, rename, summarise, summarize
library(grid)
library(gridExtra)
package 㤼㸱gridExtra㤼㸲 was built under R version 4.0.5
Attaching package: 㤼㸱gridExtra㤼㸲
The following object is masked from 㤼㸱package:dplyr㤼㸲:
combine
library(reshape2)
package 㤼㸱reshape2㤼㸲 was built under R version 4.0.5
Attaching package: 㤼㸱reshape2㤼㸲
The following objects are masked from 㤼㸱package:data.table㤼㸲:
dcast, melt
library(scales)
library("rgdal")
package 㤼㸱rgdal㤼㸲 was built under R version 4.0.5rgdal: version: 1.5-23, (SVN revision 1121)
Geospatial Data Abstraction Library extensions to R successfully loaded
Loaded GDAL runtime: GDAL 3.2.1, released 2020/12/29
Path to GDAL shared files: G:/Documents/R/win-library/4.0/rgdal/gdal
GDAL binary built with GEOS: TRUE
Loaded PROJ runtime: Rel. 7.2.1, January 1st, 2021, [PJ_VERSION: 721]
Path to PROJ shared files: G:/Documents/R/win-library/4.0/rgdal/proj
PROJ CDN enabled: FALSE
Linking to sp version:1.4-5
To mute warnings of possible GDAL/OSR exportToProj4() degradation,
use options("rgdal_show_exportToProj4_warnings"="none") before loading rgdal.
Overwritten PROJ_LIB was G:/Documents/R/win-library/4.0/rgdal/proj
library(tmap)
library(leaflet)
package 㤼㸱leaflet㤼㸲 was built under R version 4.0.5
#use net map
#manually definen bounding box of edmonton
edm_map <- get_map(location = c(left = -113.702 , bottom = 53.366 , right = -113.317, top = 53.6855 ),
zoom = 10,
scale = 12,
maptype = "toner",
source = "osm"
)
ggmap(edm_map)

#set up map parameters
mapTheme <- function(base_size = 12) {
theme(
text = element_text( color = "black"),
plot.title = element_text(size = 18,colour = "black"),
plot.subtitle=element_text(face="italic"),
plot.caption=element_text(hjust=0),
axis.ticks = element_blank(),
panel.background = element_blank(),
panel.grid.major = element_line("grey80", size = 0.1),
strip.text = element_text(size=12),
axis.title = element_blank(),
axis.text = element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
panel.grid.minor = element_blank(),
strip.background = element_rect(fill = "grey80", color = "white"),
plot.background = element_blank(),
legend.background = element_blank(),
legend.title = element_text(colour = "black", face = "italic"),
legend.text = element_text(colour = "black", face = "italic"))
}
# Define some palettes
palette_9_colors <- c("#0DA3A0","#2999A9","#458FB2","#6285BB","#7E7CC4","#9A72CD","#B768D6","#D35EDF","#F055E9")
palette_8_colors <- c("#0DA3A0","#2D97AA","#4D8CB4","#6E81BF","#8E76C9","#AF6BD4","#CF60DE","#F055E9")
palette_7_colors <- c("#2D97AA","#4D8CB4","#6E81BF","#8E76C9","#AF6BD4","#CF60DE","#F055E9")
palette_1_colors <- c("#0DA3A0")
# Map it
bmMap <- ggmap(edm_map) + mapTheme() +
labs(title="Edmonton basemap")
bmMap

NA
NA
NA
NA
#Create map of accessibility based on data crunched by R5R Edmonton TTM combined with neighborhood shapefile.
#Explanation: https://www.infoworld.com/article/3505897/how-to-do-spatial-analysis-in-r-with-sf.html
#sf documentation: https://cran.r-project.org/web/packages/sf/sf.pdf
#Read in as poly file
Edm_hoods <- st_read("G:/Desktop/Folders/Edu/Summer 2021/Data Files/ArcGIS Files/School Data/COUNT_ELEMENTARY_schools_per_hood.shp")
Reading layer `COUNT_ELEMENTARY_schools_per_hood' from data source `G:\Desktop\Folders\Edu\Summer 2021\Data Files\ArcGIS Files\School Data\COUNT_ELEMENTARY_schools_per_hood.shp' using driver `ESRI Shapefile'
Simple feature collection with 400 features and 6 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 18949.21 ymin: 5911407 xmax: 48145.16 ymax: 5953685
Projected CRS: NAD27 / Alberta 3TM ref merid 114 W
plot(Edm_hoods) #plots all columns on the map. Can show number of schools per neighborhood

# Define the bounding box
# bbox <- Edm_hoods@bbox
neighborhood_access <- acc_20min #from r5 notebook
names(neighborhood_access) <- c("id", "accessible")
Edm_hoods_dt <- as.data.table(Edm_hoods)
names(Edm_hoods_dt) <- c("id","name","number","lon","lat","count","geometry")
Edm_hoods_dt$id <- as.character(Edm_hoods_dt$id)#need to change id to char.
Edm_hoods_dt <- left_join(Edm_hoods_dt, neighborhood_access, by = "id") #aggregated and joined data set
Edm_hoods_dt <- as.data.table(Edm_hoods_dt)
Edm_hoods_dt
Edm_hoods_dt_sf <- st_as_sf(Edm_hoods_dt) #turns it back to SF object
plot(Edm_hoods_dt_sf["accessible"], key.pos = 1) #plot the count column. Number of schools accessible within 20 minutes

NA
NA
NA
#interactive map
#resource https://cengel.github.io/R-spatial/mapping.html
#tmap documentation: https://rdrr.io/cran/tmap/man/tm_polygons.html
tm_shape(Edm_hoods_dt_sf) +
tm_polygons("accessible",
style="pretty", #or "cat" for actual count
title="Number of public\nschools accessible\nin 20 mins by neighborhood",
interactive=TRUE,
popup.vars="name",
popup.format=list()
)

tmap_mode("plot") #changes between view mode (interactive) and plot mode (static)
tmap mode set to plotting
#Interactive mapping with leaflet
#can be used to create mobile friendly java based maps.
#reference: https://cengel.github.io/R-spatial/mapping.html
#need to manually repreject the map to get it to match with web projection
Edm_hoods_WGS84 <- st_transform(Edm_hoods_dt_sf, 4326)
leaflet(Edm_hoods_WGS84) %>%
addPolygons()
pal_fun <- colorBin("YlOrRd", NULL, bins = 5) #colour options
p_popup <- paste0(Edm_hoods_WGS84$name, "<strong> - Schools reachable in 20 mins: </strong>", Edm_hoods_WGS84$accessible) #popup options
interactive_edmSchool_map <- leaflet(Edm_hoods_WGS84) %>%
addPolygons(
stroke = FALSE, # remove polygon borders
fillColor = ~pal_fun(accessible), # set fill color with function from above and value
fillOpacity = 0.6, smoothFactor = 0.5, # make it nicer
popup = p_popup,
group = "Edm school data") %>% # add popup
addTiles() %>% #automatically add basemap from OSM
addLegend("bottomright", # location
pal=pal_fun, # palette function
values=~accessible, # value to be passed to palette function
title = 'Number of public\nschools accessible\nin 20 mins by neighborhood') %>% # legend title
addLayersControl(baseGroups = c("OSM", "Carto"), #turn on or off data layer
overlayGroups = c("Edm school data"))
interactive_edmSchool_map
NA
st_write(Edm_hoods_dt, "G:/Desktop/Folders/Edu/Summer 2021/Data Files/R Code/Edm_HighSchool_Access.shp") #writes the sf file to csv
Writing layer `Edm_HighSchool_Access' to data source `G:/Desktop/Folders/Edu/Summer 2021/Data Files/R Code/Edm_HighSchool_Access.shp' using driver `ESRI Shapefile'
Writing 400 features with 7 fields and geometry type Multi Polygon.
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCmBgYHtyfQ0KI1NGIE1hcHBpbmcgb2YgRWRtb250b24uIA0KI0luc3RhbGwgcGFja2FnZXMsIGxpYnJhcnkNCg0KIyBpbnN0YWxsLnBhY2thZ2VzKCJzZiIpDQojIGluc3RhbGwucGFja2FnZXMoInRtYXAiKQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCJnZ21hcCIpDQojIGluc3RhbGwucGFja2FnZXMoImdndGhlbWVzIikNCiMgaW5zdGFsbC5wYWNrYWdlcygicmdlb3MiKQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCJncmlkIikNCiMgaW5zdGFsbC5wYWNrYWdlcygiZ3JpZEV4dHJhIikNCiMgaW5zdGFsbC5wYWNrYWdlcygicmVzaGFwZTIiKQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCJzY2FsZXMiKQ0KIyBpbnN0YWxsLnBhY2thZ2VzKGMoInJnZGFsIiwgImh0bWx3aWRnZXRzIiksIGRlcGVuZGVuY2llcyA9IFRSVUUpDQojaW5zdGFsbC5wYWNrYWdlcygicmdkYWwiKQ0KI2luc3RhbGwucGFja2FnZXMoImdlb2pzb25zZiIpDQoNCg0KbGlicmFyeShnZW9qc29uc2YpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShzcCkNCmxpYnJhcnkodG1hcCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KG1hcHRvb2xzKQ0KbGlicmFyeShnZ21hcCkNCmxpYnJhcnkoZm9yY2F0cykNCmxpYnJhcnkoZ2d0aGVtZXMpDQpsaWJyYXJ5KHJnZW9zKQ0KbGlicmFyeShicm9vbSkNCmxpYnJhcnkocGx5cikNCmxpYnJhcnkoZ3JpZCkNCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShyZXNoYXBlMikNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeSgicmdkYWwiKQ0KbGlicmFyeSh0bWFwKQ0KbGlicmFyeShsZWFmbGV0KSANCg0KDQpgYGANCg0KDQoNCg0KYGBge3J9DQojdXNlIG5ldCBtYXANCiANCiNtYW51YWxseSBkZWZpbmVuIGJvdW5kaW5nIGJveCBvZiBlZG1vbnRvbg0KZWRtX21hcCA8LSBnZXRfbWFwKGxvY2F0aW9uID0gIGMobGVmdCA9IC0xMTMuNzAyICwgYm90dG9tID0gNTMuMzY2ICwgcmlnaHQgPSAtMTEzLjMxNywgdG9wID0gNTMuNjg1NSApLCANCiAgICAgICAgem9vbSA9IDEwLA0KICAgICAgICBzY2FsZSA9IDEyLA0KICAgICAgICBtYXB0eXBlID0gInRvbmVyIiwNCiAgICAgICAgc291cmNlID0gIm9zbSINCiAgICAgICAgKQ0KDQpnZ21hcChlZG1fbWFwKQ0KDQoNCiNzZXQgdXAgbWFwIHBhcmFtZXRlcnMNCm1hcFRoZW1lIDwtIGZ1bmN0aW9uKGJhc2Vfc2l6ZSA9IDEyKSB7DQogIHRoZW1lKA0KICAgIHRleHQgPSBlbGVtZW50X3RleHQoIGNvbG9yID0gImJsYWNrIiksDQogICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTgsY29sb3VyID0gImJsYWNrIiksDQogICAgcGxvdC5zdWJ0aXRsZT1lbGVtZW50X3RleHQoZmFjZT0iaXRhbGljIiksDQogICAgcGxvdC5jYXB0aW9uPWVsZW1lbnRfdGV4dChoanVzdD0wKSwNCiAgICBheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZSgiZ3JleTgwIiwgc2l6ZSA9IDAuMSksDQogICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSwNCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImdyZXk4MCIsIGNvbG9yID0gIndoaXRlIiksDQogICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiYmxhY2siLCBmYWNlID0gIml0YWxpYyIpLA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJibGFjayIsIGZhY2UgPSAiaXRhbGljIikpDQp9DQojIERlZmluZSBzb21lIHBhbGV0dGVzDQpwYWxldHRlXzlfY29sb3JzIDwtIGMoIiMwREEzQTAiLCIjMjk5OUE5IiwiIzQ1OEZCMiIsIiM2Mjg1QkIiLCIjN0U3Q0M0IiwiIzlBNzJDRCIsIiNCNzY4RDYiLCIjRDM1RURGIiwiI0YwNTVFOSIpDQpwYWxldHRlXzhfY29sb3JzIDwtIGMoIiMwREEzQTAiLCIjMkQ5N0FBIiwiIzREOENCNCIsIiM2RTgxQkYiLCIjOEU3NkM5IiwiI0FGNkJENCIsIiNDRjYwREUiLCIjRjA1NUU5IikNCnBhbGV0dGVfN19jb2xvcnMgPC0gYygiIzJEOTdBQSIsIiM0RDhDQjQiLCIjNkU4MUJGIiwiIzhFNzZDOSIsIiNBRjZCRDQiLCIjQ0Y2MERFIiwiI0YwNTVFOSIpDQpwYWxldHRlXzFfY29sb3JzIDwtIGMoIiMwREEzQTAiKQ0KIA0KIyBNYXAgaXQNCmJtTWFwIDwtIGdnbWFwKGVkbV9tYXApICsgbWFwVGhlbWUoKSArIA0KICBsYWJzKHRpdGxlPSJFZG1vbnRvbiBiYXNlbWFwIikNCmJtTWFwDQoNCg0KDQoNCmBgYA0KDQpgYGB7cn0NCiNDcmVhdGUgbWFwIG9mIGFjY2Vzc2liaWxpdHkgYmFzZWQgb24gZGF0YSBjcnVuY2hlZCBieSBSNVIgRWRtb250b24gVFRNIGNvbWJpbmVkIHdpdGggbmVpZ2hib3Job29kIHNoYXBlZmlsZS4NCg0KI0V4cGxhbmF0aW9uOiBodHRwczovL3d3dy5pbmZvd29ybGQuY29tL2FydGljbGUvMzUwNTg5Ny9ob3ctdG8tZG8tc3BhdGlhbC1hbmFseXNpcy1pbi1yLXdpdGgtc2YuaHRtbA0KI3NmIGRvY3VtZW50YXRpb246IGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9zZi9zZi5wZGYNCg0KI1JlYWQgaW4gYXMgcG9seSBmaWxlDQpFZG1faG9vZHMgPC0gc3RfcmVhZCgiRzovRGVza3RvcC9Gb2xkZXJzL0VkdS9TdW1tZXIgMjAyMS9EYXRhIEZpbGVzL0FyY0dJUyBGaWxlcy9TY2hvb2wgRGF0YS9DT1VOVF9FTEVNRU5UQVJZX3NjaG9vbHNfcGVyX2hvb2Quc2hwIikNCnBsb3QoRWRtX2hvb2RzKSAjcGxvdHMgYWxsIGNvbHVtbnMgb24gdGhlIG1hcC4gQ2FuIHNob3cgbnVtYmVyIG9mIHNjaG9vbHMgcGVyIG5laWdoYm9yaG9vZA0KIyBEZWZpbmUgdGhlIGJvdW5kaW5nIGJveA0KIyBiYm94IDwtIEVkbV9ob29kc0BiYm94DQoNCm5laWdoYm9yaG9vZF9hY2Nlc3MgPC0gYWNjXzIwbWluICNmcm9tIHI1IG5vdGVib29rDQpuYW1lcyhuZWlnaGJvcmhvb2RfYWNjZXNzKSA8LSBjKCJpZCIsICJhY2Nlc3NpYmxlIikNCg0KRWRtX2hvb2RzX2R0IDwtIGFzLmRhdGEudGFibGUoRWRtX2hvb2RzKQ0KbmFtZXMoRWRtX2hvb2RzX2R0KSA8LSBjKCJpZCIsIm5hbWUiLCJudW1iZXIiLCJsb24iLCJsYXQiLCJjb3VudCIsImdlb21ldHJ5IikNCkVkbV9ob29kc19kdCRpZCA8LSBhcy5jaGFyYWN0ZXIoRWRtX2hvb2RzX2R0JGlkKSNuZWVkIHRvIGNoYW5nZSBpZCB0byBjaGFyLg0KDQoNCkVkbV9ob29kc19kdCA8LSBsZWZ0X2pvaW4oRWRtX2hvb2RzX2R0LCBuZWlnaGJvcmhvb2RfYWNjZXNzLCBieSA9ICJpZCIpICNhZ2dyZWdhdGVkIGFuZCBqb2luZWQgZGF0YSBzZXQNCkVkbV9ob29kc19kdCA8LSBhcy5kYXRhLnRhYmxlKEVkbV9ob29kc19kdCkNCkVkbV9ob29kc19kdA0KDQpFZG1faG9vZHNfZHRfc2YgPC0gc3RfYXNfc2YoRWRtX2hvb2RzX2R0KSAjdHVybnMgaXQgYmFjayB0byBTRiBvYmplY3QNCnBsb3QoRWRtX2hvb2RzX2R0X3NmWyJhY2Nlc3NpYmxlIl0sIGtleS5wb3MgPSAxKSAjcGxvdCB0aGUgY291bnQgY29sdW1uLiBOdW1iZXIgb2Ygc2Nob29scyBhY2Nlc3NpYmxlIHdpdGhpbiAyMCBtaW51dGVzDQoNCg0KDQpgYGANCmBgYHtyfQ0KI2ludGVyYWN0aXZlIG1hcA0KDQojcmVzb3VyY2UgaHR0cHM6Ly9jZW5nZWwuZ2l0aHViLmlvL1Itc3BhdGlhbC9tYXBwaW5nLmh0bWwNCiN0bWFwIGRvY3VtZW50YXRpb246IGh0dHBzOi8vcmRyci5pby9jcmFuL3RtYXAvbWFuL3RtX3BvbHlnb25zLmh0bWwNCg0KdG1fc2hhcGUoRWRtX2hvb2RzX2R0X3NmKSArDQogIHRtX3BvbHlnb25zKCJhY2Nlc3NpYmxlIiwgDQogICAgICAgICAgICAgIHN0eWxlPSJwcmV0dHkiLCAjb3IgImNhdCIgZm9yIGFjdHVhbCBjb3VudCANCiAgICAgICAgICAgICAgdGl0bGU9Ik51bWJlciBvZiBwdWJsaWNcbnNjaG9vbHMgYWNjZXNzaWJsZVxuaW4gMjAgbWlucyBieSBuZWlnaGJvcmhvb2QiLA0KICAgICAgICAgICAgICBpbnRlcmFjdGl2ZT1UUlVFLA0KICAgICAgICAgICAgICBwb3B1cC52YXJzPSJuYW1lIiwNCiAgICAgICAgICAgICAgcG9wdXAuZm9ybWF0PWxpc3QoKQ0KICApDQoNCnRtYXBfbW9kZSgicGxvdCIpICNjaGFuZ2VzIGJldHdlZW4gdmlldyBtb2RlIChpbnRlcmFjdGl2ZSkgYW5kIHBsb3QgbW9kZSAoc3RhdGljKQ0KDQoNCmBgYA0KDQoNCmBgYHtyfQ0KI0ludGVyYWN0aXZlIG1hcHBpbmcgd2l0aCBsZWFmbGV0DQojY2FuIGJlIHVzZWQgdG8gY3JlYXRlIG1vYmlsZSBmcmllbmRseSBqYXZhIGJhc2VkIG1hcHMuDQojcmVmZXJlbmNlOiBodHRwczovL2NlbmdlbC5naXRodWIuaW8vUi1zcGF0aWFsL21hcHBpbmcuaHRtbA0KDQojbmVlZCB0byBtYW51YWxseSByZXByZWplY3QgdGhlIG1hcCB0byBnZXQgaXQgdG8gbWF0Y2ggd2l0aCB3ZWIgcHJvamVjdGlvbg0KRWRtX2hvb2RzX1dHUzg0IDwtIHN0X3RyYW5zZm9ybShFZG1faG9vZHNfZHRfc2YsIDQzMjYpDQoNCmxlYWZsZXQoRWRtX2hvb2RzX1dHUzg0KSAlPiUNCiAgYWRkUG9seWdvbnMoKQ0KDQoNCnBhbF9mdW4gPC0gY29sb3JCaW4oIllsT3JSZCIsIE5VTEwsIGJpbnMgPSA1KSAjY29sb3VyIG9wdGlvbnMNCg0KcF9wb3B1cCA8LSBwYXN0ZTAoRWRtX2hvb2RzX1dHUzg0JG5hbWUsICI8c3Ryb25nPiAtIFNjaG9vbHMgcmVhY2hhYmxlIGluIDIwIG1pbnM6IDwvc3Ryb25nPiIsIEVkbV9ob29kc19XR1M4NCRhY2Nlc3NpYmxlKSAjcG9wdXAgb3B0aW9ucw0KDQppbnRlcmFjdGl2ZV9lZG1TY2hvb2xfbWFwIDwtIGxlYWZsZXQoRWRtX2hvb2RzX1dHUzg0KSAlPiUNCiAgYWRkUG9seWdvbnMoDQogICAgc3Ryb2tlID0gRkFMU0UsICMgcmVtb3ZlIHBvbHlnb24gYm9yZGVycw0KICAgIGZpbGxDb2xvciA9IH5wYWxfZnVuKGFjY2Vzc2libGUpLCAjIHNldCBmaWxsIGNvbG9yIHdpdGggZnVuY3Rpb24gZnJvbSBhYm92ZSBhbmQgdmFsdWUNCiAgICBmaWxsT3BhY2l0eSA9IDAuNiwgc21vb3RoRmFjdG9yID0gMC41LCAjIG1ha2UgaXQgbmljZXINCiAgICBwb3B1cCA9IHBfcG9wdXAsIA0KICAgIGdyb3VwID0gIkVkbSBzY2hvb2wgZGF0YSIpICU+JSAjIGFkZCBwb3B1cA0KICANCiAgYWRkVGlsZXMoKSAlPiUgI2F1dG9tYXRpY2FsbHkgYWRkIGJhc2VtYXAgZnJvbSBPU00NCiAgYWRkTGVnZW5kKCJib3R0b21yaWdodCIsICAjIGxvY2F0aW9uDQogICAgICAgICAgICBwYWw9cGFsX2Z1biwgICAgIyBwYWxldHRlIGZ1bmN0aW9uDQogICAgICAgICAgICB2YWx1ZXM9fmFjY2Vzc2libGUsICAjIHZhbHVlIHRvIGJlIHBhc3NlZCB0byBwYWxldHRlIGZ1bmN0aW9uDQogICAgICAgICAgICB0aXRsZSA9ICdOdW1iZXIgb2YgcHVibGljXG5zY2hvb2xzIGFjY2Vzc2libGVcbmluIDIwIG1pbnMgYnkgbmVpZ2hib3Job29kJykgJT4lICMgbGVnZW5kIHRpdGxlDQoNCiAgYWRkTGF5ZXJzQ29udHJvbChiYXNlR3JvdXBzID0gYygiT1NNIiwgIkNhcnRvIiksICN0dXJuIG9uIG9yIG9mZiBkYXRhIGxheWVyDQogICAgICAgICAgICAgICAgICAgb3ZlcmxheUdyb3VwcyA9IGMoIkVkbSBzY2hvb2wgZGF0YSIpKSAgDQoNCg0KaW50ZXJhY3RpdmVfZWRtU2Nob29sX21hcA0KDQpgYGANCg0KDQoNCg0KYGBge3J9DQojRXhwb3J0DQoNCnNhdmVXaWRnZXQoaW50ZXJhY3RpdmVfZWRtU2Nob29sX21hcCwgJ0c6L0Rlc2t0b3AvRm9sZGVycy9FZHUvU3VtbWVyIDIwMjEvRGF0YSBGaWxlcy9SIENvZGUvaW50ZXJhY3RpdmVfZWRtU2Nob29sX21hcC5odG1sJywgc2VsZmNvbnRhaW5lZCA9IEZBTFNFKQ0KDQpzdF93cml0ZShFZG1faG9vZHNfZHQsICJHOi9EZXNrdG9wL0ZvbGRlcnMvRWR1L1N1bW1lciAyMDIxL0RhdGEgRmlsZXMvUiBDb2RlL0VkbV9IaWdoU2Nob29sX0FjY2Vzcy5zaHAiKSAjd3JpdGVzIHRoZSBzZiBmaWxlIHRvIGNzdg0KI3NlZSBoZXJlIGZvciBkaWZmZXJlbnQgZXhwb3J0IG9wdGlvbnMgaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3NmL3ZpZ25ldHRlcy9zZjIuaHRtbA0KDQojRWRtX2hvb2RzX2dqIDwtIHNmX2dlb2pzb24oRWRtX2hvb2RzX2R0X3NmKUFwcGFyZW50bHkgZG9lc24ndCBuZWVkIHRvIGJlIGNvbnZlcnRlZCwgc3Rfd3JpdGUgb25seSB3cml0ZXMgc2YgZmlsZXMuLi4/DQoNCmJib3ggPSBzdF9iYm94KGMoeG1pbj0tMTIwLjAwLCB5bWluPTQ4Ljk5LCB4bWF4PS0xMDkuOTksIHltYXg9NjAuMDApKQ0KDQpFZG1fY3JvcF9BQiA8LSBzdF9jcm9wKEVkbV9ob29kc19kdF9zZiwgYmJveCkNCg0KRWRtX2hvb2RzX2R0X3NmPC0gYXMuc2YoRWRtX2hvb2RzX2R0X3NmLCBleHRlbnQgPSBiYm94KQ0KI3N0X3dyaXRlKEVkbV9ob29kc19kdF9zZiwgIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvU3VtbWVyIDIwMjEvRGF0YSBGaWxlcy9SIENvZGUvRWRtX2hvb2RzX2R0Lmdlb2pzb24iKQ0KI3N0X3dyaXRlKEVkbV9ob29kc19kdF9zZiwgIkc6L0Rlc2t0b3AvRm9sZGVycy9FZHUvU3VtbWVyIDIwMjEvRGF0YSBGaWxlcy9SIENvZGUvRWRtX2hvb2RzX0NTVi5jc3YiKQ0KDQoNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K